home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / transform library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  9.8 KB  |  311 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     operations on transforms    
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1993 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.     #include <Memory.h>
  7. #include "graphics libraries.h"
  8.  
  9. gxViewPort GetTransformViewPort(gxTransform xform)
  10. {
  11.     short portCount;
  12.  
  13.     if (xform == nil)
  14.         xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
  15.     portCount = GXGetTransformViewPorts(xform, nil);
  16.     if (portCount == 0)
  17.         return nil;
  18.     else if (portCount <= 10) { /* use the stack if there's a reasonable number of ports */
  19.         gxViewPort ports[10];
  20.  
  21.         GXGetTransformViewPorts(xform, ports);
  22.         return ports[0];
  23.     } else {                /* else get memory from the heap */
  24.         gxViewPort *ports;
  25.         gxViewPort port;
  26.  
  27.         ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
  28.         GXGetTransformViewPorts(xform, ports);
  29.         port = ports[0];
  30.         DisposePtr((Ptr) ports);
  31.         return port;
  32.     }
  33. }
  34.  
  35. void SetTransformViewPort(gxTransform xForm, gxViewPort port)
  36. {
  37.     GXSetTransformViewPorts(xForm, 1, &port);
  38. }
  39.  
  40.  
  41. void AddToTransformViewPort(gxTransform xform, gxViewPort newPort)
  42. {
  43.     gxViewPort *ports, *portPtr;
  44.     short portCount, count;
  45.  
  46.     if (xform == nil)
  47.         xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
  48.     count = portCount = GXGetTransformViewPorts(xform, nil) + 1;
  49.     portPtr = ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
  50.     GXGetTransformViewPorts(xform, ports);
  51.     while (--count > 0)                /* do nothing if port order is already in transform */
  52.         if (*portPtr++ == newPort) 
  53.             goto disposeTemp;
  54.     *portPtr = newPort;
  55.     GXSetTransformViewPorts(xform, portCount, ports);
  56. disposeTemp:
  57.     DisposePtr((Ptr) ports);
  58. }
  59.  
  60. void SetShapeViewPort(gxShape sh, gxViewPort port)
  61. {
  62.     GXSetShapeViewPorts(sh, 1, &port);
  63. }
  64.  
  65. gxViewPort GetShapeViewPort(gxShape sh)
  66. {
  67.     return GetTransformViewPort(GXGetShapeTransform(sh));
  68. }
  69.  
  70. void SetDeepShapeViewPorts(gxShape sh, long portCount, const gxViewPort portList[])
  71. {
  72.     if (GXGetShapeType(sh) == gxPictureType) {
  73.         register short count = GXGetPicture(sh, nil, nil, nil, nil);
  74.         gxShape itemShape;
  75.         gxTransform itemTransform;
  76.  
  77.         while( count ) {
  78.             GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
  79.             if (itemTransform)
  80.                 GXSetTransformViewPorts(itemTransform, portCount, portList);
  81.             SetDeepShapeViewPorts(itemShape, portCount, portList);
  82.             --count;
  83.         }
  84.     } 
  85.     GXSetShapeViewPorts(sh, portCount, portList);
  86. }
  87.  
  88.  
  89. void SetDeepShapeTransform(gxShape sh, gxTransform xform)
  90. {
  91.     if (GXGetShapeType(sh) == gxPictureType) {
  92.         register short count = GXGetPicture(sh, nil, nil, nil, nil);
  93.         gxShape itemShape;
  94.         gxTransform itemTransform;
  95.         
  96.         while (count) {
  97.             GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
  98.             if (itemTransform) {
  99.                 gxStyle itemStyle;
  100.                 gxInk itemInk;
  101.                 
  102.                 GXGetPictureParts(sh, count, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
  103.                 GXSetPictureParts(sh, count, 1, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
  104.             }
  105.             SetDeepShapeTransform(itemShape, xform);
  106.             count--;
  107.         }
  108.     }
  109.     GXSetShapeTransform(sh, xform);
  110. }
  111.  
  112. void SetDeepShapeViewPort(gxShape sh, gxViewPort newPort)
  113. {
  114.     SetDeepShapeViewPorts(sh, 1, &newPort);
  115. }
  116.  
  117. void PreMapTransform(gxTransform source, gxMapping *map)
  118. {
  119.     gxMapping copy, xform;
  120.  
  121.     CopyToMapping(©, map);
  122.     GXGetTransformMapping(source, &xform);
  123.     MapMapping(©, &xform);
  124.     GXSetTransformMapping(source, ©);
  125. }
  126.  
  127. #ifdef debugging
  128. static void ClearBytes(char *block, long length)
  129. {
  130.     while (--length >= 0)
  131.         *block++ = 0;
  132. }
  133. #endif
  134.  
  135. /*    Set each of the default shapes' transforms to have only the gxViewPort in their gxViewPort list.
  136.     Default shapes that shared a gxTransform with each other will still share it; those with unique
  137.     gxTransform will still have unique ones.  Default shapes that shared a gxTransform with a non-
  138.     default gxShape will do so no longer:  only the default shapes have their gxTransform changed.  */
  139. void SetDefaultViewPort(gxViewPort port)
  140. {
  141.     /*    xforms contains the gxTransform for each gxShape, or nil if the gxShape shares a gxTransform
  142.         with another default gxShape.  owners contains the number of default shapes that own
  143.         the gxTransform.  offset contains the index of the gxShape's gxTransform in the xforms array,
  144.         if the gxShape share's a gxTransform with an earlier gxShape.  copied is true for transforms
  145.         that were created in this routine, and hence need to be disposed here.
  146.         
  147.         An index of zero means the default gxTransform.  owners and offsets could be folded into the
  148.         same array, as owners is only used where xforms is non-nil, and offsets where it is nil.
  149.     */
  150.     gxTransform xforms[gxPictureType + 1];
  151.     short owners[gxPictureType + 1];
  152.     short offsets[gxPictureType + 1];
  153.     boolean copied[gxPictureType + 1];
  154.     short i, j;
  155.  
  156. /* the following lines are desirable when debugging with memory flipping enabled */
  157. #ifdef debugging    
  158.     ClearBytes((char *) xforms, sizeof(xforms));
  159.     ClearBytes((char *) owners, sizeof(owners));
  160.     ClearBytes((char *) offsets, sizeof(offsets));
  161.     ClearBytes((char *) copied, sizeof(copied));
  162. #endif
  163.     /* collect the transforms into the arrays */
  164.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  165.         xforms[i] = GXGetShapeTransform(GXGetDefaultShape(i));
  166.         owners[i] = 1;
  167.         copied[i] = false;
  168.             
  169.         for (j = gxEmptyType; j < i; j++)
  170.             if (xforms[i] == xforms[j]) {
  171.                 xforms[i] = nil;
  172.                 offsets[i] = j;
  173.                 owners[j]++;
  174.                 break;
  175.             }
  176.     }
  177.     
  178.     /* make copies of the transforms, where necessary */
  179.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  180.         gxTransform xform = xforms[i];
  181.         gxViewPort oldPort;
  182.         
  183.         if (xform == nil) continue;
  184.         
  185.         /* maybe the transform already has the right port */
  186.         if (GXGetTransformViewPorts(xform, nil) == 1 && (GXGetTransformViewPorts(xform, &oldPort), oldPort) == port)
  187.             continue;
  188.         if (GXGetTransformOwners(xform) != owners[i]) {
  189.             /* some of the owners aren't default shapes */
  190.             xforms[i] = xform = GXCopyToTransform(nil, xform);
  191.             copied[i] = true;
  192.         }
  193.         GXSetTransformViewPorts(xform, 1, &port);
  194.     }
  195.     
  196. #ifdef debugging    
  197.     GXIgnoreGraphicsNotice(transform_already_set);
  198. #endif
  199.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  200.         gxTransform xform = xforms[i];
  201.         
  202.         GXSetShapeTransform(GXGetDefaultShape(i), xform ? xform : xforms[offsets[i]]);
  203.         if (copied[i])
  204.             GXDisposeTransform(xform);
  205.     }
  206. #ifdef debugging    
  207.     GXPopGraphicsNotice();
  208. #endif
  209. #undef defaultType
  210. }
  211.  
  212. gxViewGroup CopyViewGroup(gxViewGroup group)
  213. {
  214.     /* create a new view group */
  215.     gxViewGroup newGroup = GXNewViewGroup();
  216.  
  217.     /* copy the view device list */
  218.     {    long deviceCount = GXGetViewGroupViewDevices(group, nil), count = deviceCount;
  219.         gxViewDevice *deviceList = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice)), *list = deviceList;
  220.         GXGetViewGroupViewDevices(group, deviceList);
  221.         while (count--)
  222.         {    GXSetViewDeviceViewGroup(*list = GXCopyToViewDevice(nil, *list), newGroup);
  223.             list++;
  224.         }
  225.         DisposePtr((Ptr) deviceList);
  226.     }
  227.  
  228.     /* copy the view port list */
  229.     {    long portCount = GXGetViewGroupViewPorts(group, nil), count = portCount;
  230.         gxViewPort *oldPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *oldList = oldPortList;
  231.         gxViewPort *newPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *newList = newPortList;
  232.         GXGetViewGroupViewPorts(group, oldPortList);
  233.         while (count--)
  234.             GXSetViewPortViewGroup(*newList++ = GXCopyToViewPort(nil, *oldList++), newGroup);
  235.  
  236.     /* copy the view port hierarchy */
  237.         oldList = oldPortList; newList = newPortList;
  238.         for (count = portCount; count--; newList++)
  239.         {    gxViewPort parent = GXGetViewPortParent(*oldList++);
  240.             if (parent)
  241.             {    gxViewPort *optr = oldPortList, *nptr = newPortList;
  242.                 long pcnt = portCount;
  243.                 boolean match = false;
  244.                 while (pcnt-- && !(match = *optr == parent)) { optr++; nptr++; }
  245.                 if (match) GXSetViewPortParent(*newList, *nptr);
  246.             }
  247.         }
  248.         DisposePtr((Ptr) newPortList);
  249.         DisposePtr((Ptr) oldPortList);
  250.     }
  251.     return newGroup;
  252. }
  253.  
  254. /* the newGroup should have at least as many viewPorts in it as the oldGroup */
  255. /* ideally, newGroup and oldGroup should be copies of each other */
  256. gxTransform ChangeTransformViewGroup(gxTransform xform, gxViewGroup oldGroup, gxViewGroup newGroup)
  257. {
  258.     long oldPortCount = GXGetViewGroupViewPorts(oldGroup, nil);
  259.     long newPortCount = GXGetViewGroupViewPorts(newGroup, nil);
  260.     long xformPortCount = GXGetTransformViewPorts(xform, nil);
  261.     gxViewPort *oldPortList = (gxViewPort *) NewPtr(oldPortCount * sizeof(gxViewPort));
  262.     gxViewPort *newPortList = (gxViewPort *) NewPtr(newPortCount * sizeof(gxViewPort));
  263.     gxViewPort *xformPortList = (gxViewPort *) NewPtr(xformPortCount * sizeof(gxViewPort));
  264.     GXGetViewGroupViewPorts(oldGroup, oldPortList);
  265.     GXGetViewGroupViewPorts(newGroup, newPortList);
  266.     GXGetTransformViewPorts(xform, xformPortList);
  267.     {    long xcnt = xformPortCount;
  268.         gxViewPort *xptr = xformPortList;
  269.         while (xcnt--)
  270.         {    gxViewPort order = *xptr, *optr = oldPortList, *nptr = newPortList;
  271.             long pcnt = oldPortCount;
  272.             boolean match = false;
  273.             while (pcnt-- && !(match = *optr == order)) { optr++; nptr++; }
  274.             if (match) *xptr = *nptr;
  275.             xptr++;
  276.         }
  277.     }
  278.     GXSetTransformViewPorts(xform, xformPortCount, xformPortList);
  279.     DisposePtr((Ptr) xformPortList);
  280.     DisposePtr((Ptr) newPortList);
  281.     DisposePtr((Ptr) oldPortList);
  282.     return xform;
  283. }
  284.  
  285. gxShape ChangeShapeViewGroup(gxShape source, gxViewGroup oldGroup, gxViewGroup newGroup)
  286. {
  287.     gxTransform xform = GXGetShapeTransform(source);
  288.     if (GXGetTransformOwners(xform) > 1)            /* is it shared? */
  289.     {    xform = GXCopyToTransform(nil, xform);
  290.         GXSetShapeTransform(source, xform);
  291.         GXDisposeTransform(xform);
  292.     }
  293.     ChangeTransformViewGroup(xform, oldGroup, newGroup);
  294.     return source;
  295. }
  296.  
  297. gxTransform SeparateShapeTransform(gxShape source)
  298. {
  299.     gxTransform old = GXCloneTransform(GXGetShapeTransform(source)), xnew = GXCopyToTransform(nil, old);
  300.     GXSetShapeTransform(source, xnew);
  301.     GXDisposeTransform(xnew);
  302.     return old;
  303. }
  304.  
  305. void ReuniteShapeTransform(gxShape target, gxTransform separate)
  306. {
  307.     GXSetShapeTransform(target, separate);
  308.     GXDisposeTransform(separate);
  309.     return;
  310. }
  311.